// let a = { a: 1, b: 2, c: () => { return 1 }, d: [1, 23, 4] }
let a = { a: 1, b: 2, d: [1, 23, 4] }

// 为啥不建议用 JSON.parse(JSON.stringify(obj)) 因为如果对象自身嵌套了自身就会无限嵌套导致此方法报错

// 方法1 使用 map 数据对象进行深拷贝
/**
 * 解释 typeof xxx 的结果有8种可能 
 * undefined boolean number string symbol function object bigint
 * 这样解释下面的代码即是 除了 object 这种比较特殊的数据类型其他都可直接去赋值进行拷贝
 * 剩下object之后再将其针对 数组=[] 这 对象={} 两种具体情况进行处理即可
 * 在处理对象和数组的时候巧妙使用循环和递归
 * @param {*} params 
 */
function deepCopy3(params) {
    const objectMap = new Map();
    const _deepClone = (value) => {
        const type = typeof value;
        if (type !== 'object' || type === null) {
            return value;
        }
        if (objectMap.has(value)) {
            return objectMap.get(value);
        }
        const result = Array.isArray(value) ? [] : {};
        objectMap.set(value, result);
        console.log("222 objectMap---->", objectMap)
        for (const key in value) {
            result[key] = _deepClone(value[key])
        }
        return result
    }
    return _deepClone(params)
}

/**
 * 注意只能在浏览器环境使用不能在nodejs环境中使用
 * 使用消息 MessageChannel
 * 可在不同的 窗口 - iframe - Web Worker 之间进行通信
 * port1 发送消息 port2 接收消息
 */
function deepCopy4(params) {
    return new Promise(resolve => {
        let { port1, port2 } = new MessageChannel();
        port1.postMessage(params);
        port2.onmessage = (msg) => {
            resolve(msg.data);
        }
    })
}

let a2 = deepCopy3(a)
console.log("333---- a2---->", a2)


console.log(111, a == a)
console.log(222, a == a2)

deepCopy4(a).then(b=> {
    console.log('拷贝a后的b是', b);
})